﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Benefit.Service.ServerData
{
    public class ServiceT_TradeDetail_History : Benefit.Interface.ServerData.IT_TradeDetail_History
    {
        Benefit.DB.DBManager db = null;
        public ServiceT_TradeDetail_History(Benefit.DB.DBManager db)
        {
            this.db = db;
        }


        /// <summary>
        /// 查询结算后的成交明细情况
        /// </summary>
        /// <param name="accountid"></param>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public System.Collections.Generic.List<Models.ServerData.T_TradeDetail_History> GetInfo(string pdate)
        {
            List<Models.ServerData.T_TradeDetail_History> tth = new List<Models.ServerData.T_TradeDetail_History>();
            Interface.ServerData.IT_Settle_History tsh = new ServerData.ServiceT_Settle_History(db);
            //T_Settle_History tsh = new T_Settle_History();
            int settlementid = tsh.GetDayMaxSettlementInfoId(pdate);
            if (settlementid != -1)
            {
                tth = GetTradeDetailHistory(settlementid, pdate);
            }
            return tth;
        }

        /// <summary>
        /// 查询某天最大结算编号的成交明细
        /// </summary>
        /// <param name="settlementid">结算编号</param>
        /// <param name="pdate">日期</param>
        /// <returns></returns>
        public System.Collections.Generic.List<Models.ServerData.T_TradeDetail_History> GetTradeDetailHistory(int settlementid, string pdate)
        {
            DavidDB.ADO.DBManager dbmanager = new DavidDB.ADO.DBManager();
            System.Collections.Generic.List<Models.ServerData.T_TradeDetail_History> tth = new System.Collections.Generic.List<Models.ServerData.T_TradeDetail_History>();
            string sql = "select * from T_TradeDetail_History where SettlementId='" + settlementid + "' and tradingday='" + pdate + "'";
            dynamic sdr = dbmanager.ExecuteReader(sql);
            while (sdr.Read())
            {
                Models.ServerData.T_TradeDetail_History s = new Models.ServerData.T_TradeDetail_History();
                s.AccountId = Convert.ToInt32(sdr["accountid"]);
                s.TradeDate = Convert.ToInt32(sdr["TradeDate"]);
                s.BrokerId = Convert.ToString(sdr["Brokerid"]);
                s.BrokerOrderseq = Convert.ToInt32(sdr["BrokerOrderseq"]);
                s.BusinessUnit = Convert.ToString(sdr["BusinessUnit"]);
                s.ClearingPartid = Convert.ToString(sdr["ClearingPartid"]);
                s.ClientId = Convert.ToString(sdr["ClientId"]);
                s.CloseProfit = Convert.ToDouble(sdr["CloseProfit"]);
                s.Commission = Convert.ToDouble(sdr["Commission"]);
                s.DeliveryDate = Convert.ToString(sdr["DeliveryDate"]);
                s.Direction = Convert.ToString(sdr["Direction"]);
                s.ExchangeId = sdr["ExchangeId"].ToString();
                s.ExchangeInstid = Convert.ToString(sdr["ExchangeInstid"]);
                s.HedgeFlag = Convert.ToString(sdr["HedgeFlag"]);
                s.Id = Convert.ToInt32(sdr["Id"]);
                s.InstrumentId = Convert.ToString(sdr["InstrumentId"]);
                s.Investorid = Convert.ToString(sdr["Investorid"]);
                s.OffsetFlag = Convert.ToString(sdr["OffsetFlag"]);
                s.OrderLocalid = Convert.ToString(sdr["OrderLocalid"]);
                s.OrderRef = Convert.ToString(sdr["OrderRef"]);
                s.OrderSysId = Convert.ToString(sdr["OrderSysId"]);
                s.ParticiPantid = Convert.ToString(sdr["ParticiPantid"]);
                s.PriceSourceType = Convert.ToString(sdr["PriceSourceType"]);
                s.ProductId = Convert.ToString(sdr["ProductId"]);
                s.SequenceNo = Convert.ToInt32(sdr["SequenceNo"]);
                s.SettleMentId = Convert.ToInt32(sdr["SettleMentId"]);
                s.TotalCost = Convert.ToDouble(sdr["TotalCost"]);
                s.TradeId = Convert.ToString(sdr["TradeId"]);
                s.TradePrice = Convert.ToDouble(sdr["TradePrice"]);
                s.Traderid = Convert.ToString(sdr["Traderid"]);
                s.TradeTime = Convert.ToInt32(sdr["TradeTime"]);
                s.TradeType = Convert.ToString(sdr["TradeType"]);
                s.TradingDay = Convert.ToString(sdr["TradingDay"]);
                s.TradingRole = Convert.ToString(sdr["TradingRole"]);
                s.UserId = Convert.ToString(sdr["UserId"]);
                s.Volume = Convert.ToInt32(sdr["Volume"]);
                s.CloseProfit2 = Convert.ToDouble(sdr["CloseProfit2"]);
                tth.Add(s);
            }
            sdr.Close();
            dbmanager.Commit();
            dbmanager.Dispose();
            return tth;
        }

        /// <summary>
        /// 每天都需要执行的把Server中的数据导入到分析系统中的方法
        /// </summary>
        /// <param name="pdate">日期</param>
        public void CopyServerTradeDetailHistoryDataIntoBenefit(string pdate)
        {
            Interface.ServerData.IT_TradeDetail_History h = new ServerData.ServiceT_TradeDetail_History(db);
            // Models.ServerData.T_TradeDetail_History h = new Models.ServerData.T_TradeDetail_History();
            List<Models.ServerData.T_TradeDetail_History> tth = h.GetInfo(pdate);
            foreach (Models.ServerData.T_TradeDetail_History ha in tth)
            {
                db.TradeDetailHistory.Add(ha);
            }
            db.SaveChanges();
        }


        /// <summary>
        /// 删除某日的所有持仓明细记录
        /// </summary>
        /// <param name="pdate"></param>
        public void DeleteDayTradeDetailHistoryFromBenefit(string pdate)
        {
            var historys = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) select t;
            foreach (Models.ServerData.T_TradeDetail_History ha in historys)
            {
                db.TradeDetailHistory.Remove(ha);
            }
            db.SaveChanges();
        }




        #region 合约统计
        /// <summary>
        /// 获取某日一个账户所交易的不同合约
        /// </summary>
        /// <param name="pdate"></param>
        /// <param name="accountid"></param>
        /// <returns></returns>
        public List<string> GetAccountDayInstrument(string pdate, int serverAccountid)
        {
            DavidDB.ADO.DBManager dbmanager = new DavidDB.ADO.DBManager();
            List<string> instruments = new List<string>();
            string sql = "select distinct InstrumentId from T_TradeDetail_History where tradingday='" + pdate + "' and AccountId=" + serverAccountid;
            dynamic sdr = dbmanager.ExecuteReader(sql);
            while (sdr.Read())
            {
                instruments.Add(sdr[0].ToString());
            }
            sdr.Close();
            dbmanager.Commit();
            dbmanager.Dispose();
            return instruments;
        }
        /// <summary>
        /// 得到查询日的交易次数(如果第一天有一手持仓，第二天平掉，那手平仓将视为第一天的交易次数)
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public int GetInstrumentTradeCountOnDay(string pdate, int serverAccountId, string instrument, string direction)
        {
            int count = 0;
            var historys = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.Direction.Equals(direction) && t.AccountId == serverAccountId && t.InstrumentId.Equals(instrument) select t;
            count = historys.Count();
            return count;
        }
        /// <summary>
        /// 获取某日交易笔数
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public int GetDayInstrumentBillCount(string pdate, int serverAccountId, string instrumentid, string direction)
        {
            int count = 0;
            var historys = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.Direction.Equals(direction) && t.AccountId == serverAccountId && t.InstrumentId.Equals(instrumentid) select t;
            if (historys.Count() > 0)
            {
                count = historys.Sum(a => a.Volume);
            }
            return count;
        }
        /// <summary>
        /// 获取某日总亏损
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public double GetDayInstrumentAllLose(string pdate, int serverAccountId, string instrument, string direction)
        {
            double count = 0;
            var historys = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.AccountId == serverAccountId && t.Direction.Equals(direction) && (t.CloseProfit - t.Commission) < 0 && t.InstrumentId.Equals(instrument) select t;
            if (historys.Count() > 0)
            {
                count = historys.Sum(a => a.CloseProfit) - historys.Sum(a => a.Commission);
            }
            return Math.Abs(count);
        }
        /// <summary>
        /// 获取某日总盈利
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public double GetDayInstrumentAllWin(string pdate, int serverAccountId, string instrument, string direction)
        {
            double count = 0;
            var historys = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.AccountId == serverAccountId && t.Direction.Equals(direction) && (t.CloseProfit - t.Commission) > 0 && t.InstrumentId.Equals(instrument) select t;
            if (historys.Count() > 0)
            {
                count = historys.Sum(a => a.CloseProfit) - historys.Sum(a => a.Commission);

            }
            return count;
        }



        /// <summary>
        /// 获取当天盈利次数
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public int GetDayInstrumentWinCount(string pdate, int serverAccountId, string instrument, string direction)
        {
            int count = 0;
            var query = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.AccountId == serverAccountId && t.Direction.Equals(direction) && (t.CloseProfit - t.Commission) > 0 && t.InstrumentId.Equals(instrument) select t;
            count = query.Count();
            return count;
        }
        /// <summary>
        /// 获取当天平单次数
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public int GetDayInstrumentPingCount(string pdate, int serverAccountId, string instrument, string direction)
        {
            int count = 0;
            var query = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.Direction.Equals(direction) && t.AccountId == serverAccountId && !t.OffsetFlag.Equals("0") && (t.CloseProfit - t.Commission) == 0 && t.InstrumentId.Equals(instrument) select t;
            count = query.Count();
            return count;
        }
        /// <summary>
        /// 获取当天亏损次数
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public int GetDayInstrumentLoseCount(string pdate, int serverAccountId, string instrument, string direction)
        {
            int count = 0;
            var query = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.AccountId == serverAccountId && t.Direction.Equals(direction) && (t.CloseProfit - t.Commission) < 0 && t.InstrumentId.Equals(instrument) select t;
            if (query.Count() > 0)
            {
                count = query.Count();
            }
            return count;
        }
        /// <summary>
        /// 获取最大回撤
        /// </summary>
        /// <param name="pdate"></param>
        /// <param name="serverAccountId"></param>
        /// <returns></returns>
        public double GetInstrumentMaxReturn(string pdate, int serverAccountId, string instrument, string direction)
        {
            double maxReturn = 0;
            double allValue = 0;
            var query = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.Direction.Equals(direction) && t.AccountId == serverAccountId && t.InstrumentId.Equals(instrument) select t;
            foreach (Models.ServerData.T_TradeDetail_History h in query)
            {
                allValue += h.CloseProfit - h.Commission;
                if (maxReturn < allValue)
                {
                    maxReturn = allValue;
                }
            }
            if (maxReturn > 0)
            {
                maxReturn = 0;
            }
            return maxReturn;
        }
        /// <summary>
        /// 获取当天手续费
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public double GetDayInstrumentCommission(string pdate, int serverAccountId, string instrument, string direction)
        {
            double count = 0;
            var query = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.AccountId == serverAccountId && t.Direction.Equals(direction) && t.InstrumentId.Equals(instrument) select t;
            if (query.Count() > 0)
            {
                count = query.Sum(a => a.Commission);
            }
            return count;
        }
        /// <summary>
        /// 获取当天平仓盈亏
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public double GetDayInstrumentCloseProfit(string pdate, int serverAccountId, string instrument, string direction)
        {
            double count = 0;
            var query = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.AccountId == serverAccountId && t.Direction.Equals(direction) && t.InstrumentId.Equals(instrument) && !t.OffsetFlag.Equals("0") select t;
            if (query.Count() > 0)
            {
                count = query.Sum(a => a.CloseProfit);
            }
            return count;
        }



        #endregion

        #region 品种统计
        /// <summary>
        /// 获取某日一个账户所交易的不同品种
        /// </summary>
        /// <param name="pdate"></param>
        /// <param name="accountid"></param>
        /// <returns></returns>
        public List<string> GetAccountDayProduct(string pdate, int serverAccountid)
        {
            DavidDB.ADO.DBManager dbmanager = new DavidDB.ADO.DBManager();
            List<string> products = new List<string>();
            string sql = "select distinct ProductId from T_TradeDetail_History where tradingday='" + pdate + "' and AccountId=" + serverAccountid;
            dynamic sdr = dbmanager.ExecuteReader(sql);
            while (sdr.Read())
            {
                products.Add(sdr[0].ToString());
            }
            sdr.Close();
            dbmanager.Commit();
            dbmanager.Dispose();
            return products;
        }
        /// <summary>
        /// 获取某日交易笔数
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public int GetDayProductBillCount(string pdate, int serverAccountId, string productid, string direction)
        {
            int count = 0;
            var historys = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.Direction.Equals(direction) && t.AccountId == serverAccountId && t.ProductId.Equals(productid) select t;
            if (historys.Count() > 0)
            {
                count = historys.Sum(a => a.Volume);
            }
            return count;
        }
        /// <summary>
        /// 获取某日总亏损
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public double GetDayProductAllLose(string pdate, int serverAccountId, string product, string direction)
        {
            double count = 0;
            var historys = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.AccountId == serverAccountId && t.Direction.Equals(direction) && (t.CloseProfit - t.Commission) < 0 && t.ProductId.Equals(product) select t;
            if (historys.Count() > 0)
            {
                count = historys.Sum(a => a.CloseProfit) - historys.Sum(a => a.Commission);
            }
            return Math.Abs(count);
        }
        /// <summary>
        /// 获取某日总盈利
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public double GetDayProductAllWin(string pdate, int serverAccountId, string product, string direction)
        {
            double count = 0;
            var historys = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.AccountId == serverAccountId && t.Direction.Equals(direction) && (t.CloseProfit - t.Commission) > 0 && t.ProductId.Equals(product) select t;
            if (historys.Count() > 0)
            {
                count = historys.Sum(a => a.CloseProfit) - historys.Sum(a => a.Commission);
            }
            return count;
        }
        /// <summary>
        /// 获取当天平单次数
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public int GetDayProductPingCount(string pdate, int serverAccountId, string product, string direction)
        {
            int count = 0;
            var query = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.Direction.Equals(direction) && t.AccountId == serverAccountId && !t.OffsetFlag.Equals("0") && (t.CloseProfit - t.Commission) == 0 && t.ProductId.Equals(product) select t;
            count = query.Count();
            return count;
        }
        /// <summary>
        /// 获取当天亏损次数
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public int GetDayProductLoseCount(string pdate, int serverAccountId, string product, string direction)
        {
            int count = 0;
            var query = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.AccountId == serverAccountId && t.Direction.Equals(direction) && (t.CloseProfit - t.Commission) < 0 && t.ProductId.Equals(product) select t;
            if (query.Count() > 0)
            {
                count = query.Count();
            }
            return count;
        }
        /// <summary>
        /// 获取最大回撤
        /// </summary>
        /// <param name="pdate"></param>
        /// <param name="serverAccountId"></param>
        /// <returns></returns>
        public double GetProductMaxReturn(string pdate, int serverAccountId, string product, string direction)
        {
            double maxReturn = 0;
            double allValue = 0;
            var query = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.Direction.Equals(direction) && t.AccountId == serverAccountId && t.ProductId.Equals(product) select t;
            foreach (Models.ServerData.T_TradeDetail_History h in query)
            {
                allValue += h.CloseProfit - h.Commission;
                if (maxReturn < allValue)
                {
                    maxReturn = allValue;
                }
            }
            if (maxReturn > 0)
            {
                maxReturn = 0;
            }
            return maxReturn;
        }


        /// <summary>
        /// 平均单笔盈利
        /// </summary>
        /// <param name="pdate"></param>
        /// <param name="serverAccountId"></param>
        /// <returns></returns>
        public double GetProductAvgBillBenefit(string pdate, int serverAccountId, string product, string direction)
        {
            double returnValue = 0;
            var query = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.Direction.Equals(direction) && t.AccountId == serverAccountId && t.ProductId.Equals(product) select t;
            if (query.Count() > 0)
            {
                int shoushu = query.Where(a => a.Volume > 0).Sum(a => a.Volume);
                if (shoushu == 0)
                {
                    shoushu = 1;
                }
                double BillBenefit = query.Sum(a => a.CloseProfit);
                return returnValue = BillBenefit / shoushu;
            }
            return returnValue;
        }

        /// <summary>
        /// 获取当天手续费
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public double GetDayProductCommission(string pdate, int serverAccountId, string product, string direction)
        {
            double count = 0;
            var query = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.AccountId == serverAccountId && t.Direction.Equals(direction) && t.ProductId.Equals(product) select t;
            if (query.Count() > 0)
            {
                count = query.Sum(a => a.Commission);
            }
            return count;
        }
        /// <summary>
        /// 获取当天平仓盈亏
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public double GetDayProductCloseProfit(string pdate, int serverAccountId, string product, string direction)
        {
            double count = 0;
            var query = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.AccountId == serverAccountId && t.Direction.Equals(direction) && t.ProductId.Equals(product) && !t.OffsetFlag.Equals("0") select t;
            if (query.Count() > 0)
            {
                count = query.Sum(a => a.CloseProfit);
            }
            return count;
        }
        /// <summary>
        /// 获取当天盈利次数
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public int GetDayProductWinCount(string pdate, int serverAccountId, string product, string direction)
        {
            int count = 0;
            var query = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.AccountId == serverAccountId && t.Direction.Equals(direction) && (t.CloseProfit - t.Commission) > 0 && t.ProductId.Equals(product) select t;
            count = query.Count();
            return count;
        }


        #endregion

        #region 账户统计
        /// <summary>
        /// 得到查询日的交易次数(如果第一天有一手持仓，第二天平掉，那手平仓将视为第一天的交易次数)
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public int GetTradeCountOnDay(string pdate, int serverAccountId)
        {
            int count = 0;
            var historys = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.AccountId == serverAccountId select t;
            count = historys.Count();
            return count;
        }
        /// <summary>
        /// 获取某日总亏损
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public double GetDayAllLose(string pdate, int serverAccountId)
        {
            double count = 0;
            var historys = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.AccountId == serverAccountId && t.CloseProfit < 0 select t;
            if (historys.Count() > 0)
            {
                count = historys.Sum(a => a.CloseProfit);
            }
            return count;
        }
        /// <summary>
        /// 获取某日总盈利
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public double GetDayAllWin(string pdate, int serverAccountId)
        {
            double count = 0;
            var historys = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.AccountId == serverAccountId && t.CloseProfit > 0 select t;
            if (historys.Count() > 0)
            {
                count = historys.Sum(a => a.CloseProfit);
            }
            return count;
        }

        /// <summary>
        /// 获取当天盈利次数
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public int GetDayWinCount(string pdate, int serverAccountId)
        {
            int count = 0;
            var query = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.AccountId == serverAccountId && (t.CloseProfit - t.Commission) > 0 select t;
            count = query.Count();
            return count;
        }

        /// <summary>
        /// 获取最大回撤
        /// </summary>
        /// <param name="pdate"></param>
        /// <param name="serverAccountId"></param>
        /// <returns></returns>
        public double GetMaxReturn(string pdate, int serverAccountId)
        {
            double maxReturn = 0;
            double allValue = 0;
            var query = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.AccountId == serverAccountId select t;
            foreach (Models.ServerData.T_TradeDetail_History h in query)
            {
                allValue += h.CloseProfit - h.Commission;
                if (maxReturn > allValue)
                {
                    maxReturn = allValue;
                }
            }
            if (maxReturn > 0)
            {
                maxReturn = 0;
            }
            return maxReturn;
        }


        /// <summary>
        /// 获取当天平单次数
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public int GetDayPingCount(string pdate, int serverAccountId)
        {
            int count = 0;
            var query = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.AccountId == serverAccountId && !t.OffsetFlag.Equals("0") && t.CloseProfit == 0 select t;
            count = query.Count();
            return count;
        }


        /// <summary>
        /// 获取当天亏损次数
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public int GetDayLoseCount(string pdate, int serverAccountId)
        {
            int count = 0;
            var query = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.AccountId == serverAccountId && !t.OffsetFlag.Equals("0") && (t.CloseProfit - t.Commission) < 0 select t;
            count = query.Count();
            return count;
        }
        /// <summary>
        /// 获取某日交易笔数
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public int GetDayBillCount(string pdate, int serverAccountId)
        {
            int count = 0;
            var historys = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.AccountId == serverAccountId select t;
            if (historys.Count() > 0)
            {
                count = historys.Sum(a => a.Volume);
            }
            return count;
        }
        /// <summary>
        /// 获取某日总的开仓保证金(由于保证金比较难算，暂时只用平仓盈亏总和来算)
        /// </summary>
        /// <param name="pdate"></param>
        /// <param name="serverAccountId"></param>
        /// <param name="db"></param>
        /// <returns></returns>
        public double GetAllOpenMoney(string pdate, int serverAccountId)
        {
            double count = 0f;
            var query = db.TradeDetailHistory.Where(a => a.TradingDay.Equals(pdate)).Where(a => a.AccountId == serverAccountId).ToList();
            if (query.Count() > 0)
            {
                count = query.Sum(a => a.TotalCost);
            }
            return count;
        }

        #endregion



        #region 分时统计


        /// <summary>
        /// 得到查询日分时的交易次数(如果第一天有一手持仓，第二天平掉，那手平仓将视为第一天的交易次数)
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public int GetStateTradeCountOnDay(string pdate, int serverAccountId, int state)
        {

            int count = 0;
            var historys = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.AccountId == serverAccountId select t;
            List<Models.ServerData.T_TradeDetail_History> h = new List<Models.ServerData.T_TradeDetail_History>();
            Interface.Sys.ITradeHistory th = new Sys.ServiceTradeHistory(db);
            //Models.ServerData.TradeHistory th = new Models.ServerData.TradeHistory();
            foreach (Models.ServerData.T_TradeDetail_History _h in historys)
            {
                if (th.TimeInState(state, _h.TradeTime))
                {
                    h.Add(_h);
                }
            }
            count = h.Count();
            return count;
        }

        /// <summary>
        /// 获取某日分时交易笔数
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public int GetStateDayBillCount(string pdate, int serverAccountId, int state)
        {
            int count = 0;
            var historys = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.AccountId == serverAccountId select t;
            List<Models.ServerData.T_TradeDetail_History> h = new List<Models.ServerData.T_TradeDetail_History>();
            Interface.Sys.ITradeHistory th = new Sys.ServiceTradeHistory(db);
            //Sys.TradeHistory th = new Sys.TradeHistory();
            foreach (Models.ServerData.T_TradeDetail_History _h in historys)
            {
                if (th.TimeInState(state, _h.TradeTime))
                {
                    h.Add(_h);
                }
            }
            if (h.Count() > 0)
            {
                count = h.Sum(a => a.Volume);
            }
            return count;
        }
        /// <summary>
        /// 获取某日分时总亏损
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public double GetStateDayAllLose(string pdate, int serverAccountId, int state)
        {
            double count = 0;
            var historys = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.AccountId == serverAccountId && (t.CloseProfit - t.Commission) < 0 select t;
            List<Models.ServerData.T_TradeDetail_History> h = new List<Models.ServerData.T_TradeDetail_History>();
            Interface.Sys.ITradeHistory th = new Sys.ServiceTradeHistory(db);
            //Sys.TradeHistory th = new Sys.TradeHistory();
            foreach (Models.ServerData.T_TradeDetail_History _h in historys)
            {
                if (th.TimeInState(state, _h.TradeTime))
                {
                    h.Add(_h);
                }
            }
            if (h.Count() > 0)
            {
                count = h.Sum(a => a.CloseProfit);
            }
            return Math.Abs(count);
        }
        /// <summary>
        /// 获取某日分时总盈利
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public double GetStateDayAllWin(string pdate, int serverAccountId, int state)
        {
            double count = 0;
            var historys = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.AccountId == serverAccountId && (t.CloseProfit - t.Commission) > 0 select t;
            List<Models.ServerData.T_TradeDetail_History> h = new List<Models.ServerData.T_TradeDetail_History>();
            Interface.Sys.ITradeHistory th = new Sys.ServiceTradeHistory(db);
            //Sys.TradeHistory th = new Sys.TradeHistory();
            foreach (Models.ServerData.T_TradeDetail_History _h in historys)
            {
                if (th.TimeInState(state, _h.TradeTime))
                {
                    h.Add(_h);
                }
            }
            if (h.Count() > 0)
            {
                count = historys.Sum(a => a.CloseProfit) - historys.Sum(a => a.Commission);
            }
            return count;
        }

        /// <summary>
        /// 获取当天分时盈利次数
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public int GetStateDayWinCount(string pdate, int serverAccountId, int state)
        {
            int count = 0;
            var query = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.AccountId == serverAccountId && (t.CloseProfit - t.Commission) > 0 select t;
            List<Models.ServerData.T_TradeDetail_History> h = new List<Models.ServerData.T_TradeDetail_History>();
            Interface.Sys.ITradeHistory th = new Sys.ServiceTradeHistory(db);
            //Sys.TradeHistory th = new Sys.TradeHistory();
            foreach (Models.ServerData.T_TradeDetail_History _h in query)
            {
                if (th.TimeInState(state, _h.TradeTime))
                {
                    h.Add(_h);
                }
            }
            if (h.Count() > 0)
            {
                count = h.Count();
            }
            return count;
        }

        /// <summary>
        /// 获取当天分时平仓盈亏
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public double GetDayStateCloseProfit(string pdate, int serverAccountId, int state)
        {
            double count = 0;
            var query = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.AccountId == serverAccountId select t;
            List<Models.ServerData.T_TradeDetail_History> h = new List<Models.ServerData.T_TradeDetail_History>();
            Interface.Sys.ITradeHistory th = new Sys.ServiceTradeHistory(db);
            //Sys.TradeHistory th = new Sys.TradeHistory();
            foreach (Models.ServerData.T_TradeDetail_History _h in query)
            {
                if (th.TimeInState(state, _h.TradeTime))
                {
                    h.Add(_h);
                }
            }
            if (h.Count() > 0)
            {
                count = query.Sum(a => a.CloseProfit);
            }
            return count;
        }

        /// <summary>
        /// 获取当天分时手续费
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public double GetDayStateCommission(string pdate, int serverAccountId, int state)
        {
            double count = 0;
            var query = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.AccountId == serverAccountId select t;
            List<Models.ServerData.T_TradeDetail_History> h = new List<Models.ServerData.T_TradeDetail_History>();
            Interface.Sys.ITradeHistory th = new Sys.ServiceTradeHistory(db);
            foreach (Models.ServerData.T_TradeDetail_History _h in query)
            {
                if (th.TimeInState(state, _h.TradeTime))
                {
                    h.Add(_h);
                }
            }
            if (h.Count() > 0)
            {
                count = query.Sum(a => a.Commission);
            }
            return count;
        }

        /// <summary>
        /// 获取当天分时亏损次数
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public int GetDayStateLoseCount(string pdate, int serverAccountId, int state)
        {
            int count = 0;
            var query = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.AccountId == serverAccountId && (t.CloseProfit - t.Commission) < 0 select t;
            List<Models.ServerData.T_TradeDetail_History> h = new List<Models.ServerData.T_TradeDetail_History>();
            Interface.Sys.ITradeHistory th = new Sys.ServiceTradeHistory(db);
            foreach (Models.ServerData.T_TradeDetail_History _h in query)
            {
                if (th.TimeInState(state, _h.TradeTime))
                {
                    h.Add(_h);
                }
            }
            if (h.Count() > 0)
            {
                count = query.Count();
            }
            return count;
        }

        /// <summary>
        /// 获取分时保证金
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public int GetDayStateMargin(string pdate, int serverAccountId, int state)
        {
            int count = 0;
            var query = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.AccountId == serverAccountId && (t.CloseProfit - t.Commission) < 0 select t;
            List<Models.ServerData.T_TradeDetail_History> h = new List<Models.ServerData.T_TradeDetail_History>();
            Interface.Sys.ITradeHistory th = new Sys.ServiceTradeHistory(db);
            foreach (Models.ServerData.T_TradeDetail_History _h in query)
            {
                if (th.TimeInState(state, _h.TradeTime))
                {
                    h.Add(_h);
                }
            }
            if (h.Count() > 0)
            {
                count = 0;
            }
            return count;
        }


        #endregion

        /// <summary>
        /// 获取账户平均持仓时间
        /// </summary>
        /// <param name="pdate"></param>
        /// <param name="serverAccountId"></param>
        /// <param name="db"></param>
        /// <returns></returns>
        public double GetAccountAvgPostionTime(string pdate, int serverAccountId, int accountId, int tradeHistoryId)
        {
            double count = 0;
            var allinstruments = this.GetInfo(pdate);//当日所有成交明细
            var historys = (from t in allinstruments where t.AccountId == serverAccountId orderby t.TradeTime select t).ToList();
            //     List<string> instruments = this.GetAccountDayInstrument(pdate, serverAccountId);
            long allbugTime = 0;
            long allcount = 0;
            bool changed = false;
        Restart:
            foreach (Models.ServerData.T_TradeDetail_History instrument in historys)
            {
                var bugObject = historys.Where(a => a.InstrumentId.Equals(instrument.InstrumentId)).Where(a => a.Direction.Equals("0")).FirstOrDefault();
                var saleObject = historys.Where(a => a.InstrumentId.Equals(instrument.InstrumentId)).Where(a => a.Direction.Equals("1")).FirstOrDefault();
                if (bugObject != null && saleObject != null)//如果只开仓或只平隔夜仓
                {
                    if (bugObject.TradeTime < saleObject.TradeTime)//如果平今仓
                    {
                        int buyTime = bugObject.TradeTime;
                        int saleTime = saleObject.TradeTime;
                        allcount++;
                        allbugTime += saleTime - buyTime;
                        historys.Remove(instrument);
                        historys.Remove(historys.Where(a => a.InstrumentId.Equals(instrument.InstrumentId)).Where(a => a.Direction.Equals("1")).FirstOrDefault());
                        Models.Day.YieldInHoldTime yht = new Models.Day.YieldInHoldTime();
                        yht.AccountId = accountId;
                        yht.HoldTime = saleTime - buyTime;
                        yht.TradeHistoryId = tradeHistoryId;
                        yht.Yield = Convert.ToInt32(Math.Round((((saleObject.TotalCost - bugObject.TotalCost) * 100) / bugObject.TotalCost), 2));
                        db.YieldInHoldTime.Add(yht);
                        changed = true;
                    }
                    else//平昨仓或今仓已算过
                    {
                        historys.Remove(instrument);
                        changed = true;
                    }
                    if (changed)
                    {
                        goto Restart;
                    }
                }

            }
            if (allcount != 0)
            {
                count = allbugTime / allcount;
            }
            else
            {
                count = allbugTime;
            }
            db.SaveChanges();
            return count;
        }

        #region 经纪公司收益



        /// <summary>
        /// 得到查询日经纪公司的交易次数(如果第一天有一手持仓，第二天平掉，那手平仓将视为第一天的交易次数)
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public int GetBrokerTradeCountOnDay(string pdate, string brokerid)
        {
            int count = 0;
            var historys = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.BrokerId.Equals(brokerid) select t;
            if (historys.Count() > 0)
            {
                count = historys.Count();
            }
            return count;
        }

        /// <summary>
        /// 获取某日经纪公司交易笔数
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public int GetBrokerDayBillCount(string pdate, string brokerid)
        {
            int count = 0;
            //   var historys = (from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.BrokerId.Equals(brokerid) select t).ToList();
            var historys = db.TradeDetailHistory.Where(a => a.TradingDay.Equals(pdate)).Where(a => a.BrokerId.Equals(brokerid)).ToList();
            if (historys.Count() > 0)
            {
                count = historys.Sum(a => a.Volume);
            }
            return count;
        }
        /// <summary>
        /// 获取某日经纪公司总亏损
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public double GetBrokerDayAllLose(string pdate, string brokerid)
        {
            double count = 0;
            var historys = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && (t.CloseProfit - t.Commission) < 0 && t.BrokerId.Equals(brokerid) select t;
            if (historys.Count() > 0)
            {
                count = historys.Sum(a => a.CloseProfit);
            }
            return Math.Abs(count);
        }
        /// <summary>
        /// 获取某日经纪公司总盈利
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public double GetBrokerDayAllWin(string pdate, string brokerid)
        {
            double count = 0;
            var historys = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && (t.CloseProfit - t.Commission) > 0 && t.BrokerId.Equals(brokerid) select t;
            if (historys.Count() > 0)
            {
                count = historys.Sum(a => a.CloseProfit) - historys.Sum(a => a.Commission);
            }
            return count;
        }

        /// <summary>
        /// 获取当天经纪公司盈利次数
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public int GetBrokerDayWinCount(string pdate, string brokerid)
        {
            int count = 0;
            var query = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && (t.CloseProfit - t.Commission) > 0 && t.BrokerId.Equals(brokerid) select t;
            if (query.Count() > 0)
            {
                count = query.Count();
            }
            return count;
        }

        /// <summary>
        /// 获取当天经纪公司平仓盈亏
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public double GetDayBrokerCloseProfit(string pdate, string brokerid)
        {
            double count = 0;
            var query = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.BrokerId.Equals(brokerid) select t;
            if (query.Count() > 0)
            {
                count = query.Sum(a => a.CloseProfit);
            }
            return count;
        }

        /// <summary>
        /// 获取当天经纪公司手续费
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public double GetDayBrokerCommission(string pdate, string brokerid)
        {
            double count = 0;
            var query = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && t.BrokerId.Equals(brokerid) select t;
            if (query.Count() > 0)
            {
                count = query.Sum(a => a.Commission);
            }
            return count;
        }

        /// <summary>
        /// 获取当天经纪公司亏损次数
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public int GetDayBrokerLoseCount(string pdate, string brokerid)
        {
            int count = 0;
            var query = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && (t.CloseProfit - t.Commission) < 0 && t.BrokerId.Equals(brokerid) select t;
            if (query.Count() > 0)
            {
                count = query.Count();
            }
            return count;
        }

        /// <summary>
        /// 获取经纪公司保证金
        /// </summary>
        /// <param name="pdate"></param>
        /// <returns></returns>
        public int GetDayBrokerMargin(string pdate, string brokerid)
        {
            int count = 0;
            var query = from t in db.TradeDetailHistory where t.TradingDay.Equals(pdate) && (t.CloseProfit - t.Commission) < 0 && t.BrokerId.Equals(brokerid) select t;
            if (query.Count() > 0)
            {
                count = 0;
            }
            return count;
        }




        #endregion
    }
}